package com.hyt.it.ogt.pj.data.utils;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

/**
 * 
 * @ClassName: ExecutorPoolUtil
 * @Description: 线程池工具类
 * @author huangwu
 * @date 2022年03月10日 下午1:51:56
 *
 */
public class ExecutorPoolUtil {
	private static final Logger logger = LoggerFactory.getLogger(ExecutorPoolUtil.class);
	private static ThreadPoolExecutor executorService = null;
	private static int THREAD_POOL_SIZE = 10;
	private static volatile Boolean hasInit = Boolean.FALSE;
	private static ThreadPoolTaskExecutor CREATEFILEEXECUTOR = null;


	private ExecutorPoolUtil() {

	}
	
    /**
     * 执行带返回任务的异步线程
     */
    public static <T> Future<T> submitFileExcure(Callable<T> callable) {
        ThreadPoolTaskExecutor poolTaskExecutor = CREATEFILEEXECUTOR;
        return poolTaskExecutor.submit(callable);
    }

	private static void initExecutorService() {
		try {
			ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("pj-data-service-pool-%d").build();
			executorService = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 
					0L, TimeUnit.MILLISECONDS, 
					new LinkedBlockingQueue<>(1024), 
					threadFactory, 
					new ThreadPoolExecutor.DiscardPolicy()); // 如果队列超过了1024则直接抛弃请求，也不抛出异常了
			hasInit = true;
		} catch (Exception e) {
			logger.error("初始化线程池失败", e);
		}

	}

	public static ExecutorService getExecutorService() {
		// 解决在初始化的时候没有初始成功
		if (hasInit) {
			int activeCount = ((ThreadPoolExecutor) executorService).getActiveCount();
			int poolSize = ((ThreadPoolExecutor) executorService).getMaximumPoolSize();
			if (Double.valueOf(String.valueOf(activeCount)) / poolSize >= 0.8) {
				logger.warn("PreExecutorServiceBLL 活跃线程数已达到80%，是否调整");
			}
			return executorService;
		} else {
			initExecutorService();
		}
		return executorService;
	}
}
